# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import UserError
import logging  # 导入日志模块

_logger = logging.getLogger(__name__)  # 获取当前模块的日志记录器


class SBPaymentFeeWizard(models.TransientModel):
    _name = 'sb.payment.fee.wizard'
    _description = 'Payment with Bank Fee'

    checking_id = fields.Many2one('sb.account.checking', string='Account Checking', required=True)
    partner_id = fields.Many2one('res.partner', related='checking_id.customer', readonly=True)
    journal_id = fields.Many2one(  # 修正：Many2one 字段定义错误，应为 Many2one 而非 Many22one
        'account.journal',
        string='Bank Journal',
        required=True,
        domain=[('type', 'in', ['bank', 'cash'])],
        default=lambda self: self.env['account.journal'].search(
            [('type', '=', 'bank')], limit=1
        )
    )
    payment_date = fields.Date(string='Payment Date', default=fields.Date.context_today, required=True)
    amount = fields.Monetary(string='Payment Amount', currency_field='currency_id', required=True)
    currency_id = fields.Many2one('res.currency', related='checking_id.currency_id', readonly=True)
    has_fee = fields.Boolean(string='Has Bank Fee', default=True)
    fee_amount = fields.Monetary(string='Bank Fee', currency_field='currency_id')
    fee_account_id = fields.Many2one('account.account', string='Fee Account', required=True,
                                     default=lambda self: self.env['account.account'].search([('name', '=', 'BANK_FEE')], limit=1))

    @api.onchange('has_fee')
    def _onchange_has_fee(self):
        """
        根据是否包含手续费来清空手续费金额。
        """
        if not self.has_fee:
            self.fee_amount = 0.0

    def action_confirm_payment(self):
        """
        确认付款并处理银行手续费。
        此方法将创建一个账户付款记录，并根据需要调整其凭证分录以包含银行手续费。
        """
        self.ensure_one()  # 确保向导只在一个记录上操作。

        if self.amount <= 0:
            raise UserError(_('Payment amount must be positive.'))

        # 获取交易货币和公司货币
        currency = self.currency_id or self.journal_id.currency_id or self.env.company.currency_id
        company_currency = self.env.company.currency_id

        # 计算实际进入银行的净金额
        net_bank_amount = self.amount
        if self.has_fee and self.fee_amount > 0:
            if self.fee_amount >= self.amount:
                raise UserError(_('Bank fee cannot be greater than or equal to the payment amount.'))
            net_bank_amount = self.amount - self.fee_amount

        # 创建 account.payment 记录。
        # 注意：此处 amount 依然是客户支付的总金额，后续我们将修改其关联的凭证分录。
        # 初始状态设置为 'draft' 以便修改。
        payment = self.env['account.payment'].create({
            'payment_type': 'inbound',  # 入站付款 (客户付款给我们)
            'partner_type': 'customer',  # 付款方类型为客户
            'partner_id': self.partner_id.id,  # 关联的客户
            'journal_id': self.journal_id.id,  # 使用的银行或现金日记账
            'amount': self.amount,  # 客户支付的原始总金额
            'currency_id': self.currency_id.id,  # 交易货币
            'date': self.payment_date,  # 付款日期
            'state': 'draft',  # 确保凭证处于草稿状态以便修改
        })

        # 获取付款生成的关联会计凭证（此时凭证处于草稿状态）
        move = payment.move_id

        # 添加日志输出，帮助调试
        _logger.info(f"Payment created with ID: {payment.id}, Move ID: {move.id}")

        if self.has_fee and self.fee_amount > 0:
            # 将手续费金额和净银行金额转换为公司货币
            fee_amount_company_currency = currency._convert(
                self.fee_amount, company_currency, self.env.company, self.payment_date
            )
            net_bank_amount_company_currency = currency._convert(
                net_bank_amount, company_currency, self.env.company, self.payment_date
            )

            _logger.info(f"Processing bank fee. Fee Amount: {self.fee_amount}, Net Bank Amount: {net_bank_amount}")
            _logger.info(f"Fee (Company Currency): {fee_amount_company_currency}, Net Bank (Company Currency): {net_bank_amount_company_currency}")

            # 遍历所有凭证行并打印信息，以便查看它们的实际账户和金额
            _logger.info("Current Move Lines before modification:")
            for line in move.line_ids:
                _logger.info(
                    f"  Line ID: {line.id}, Account ID: {line.account_id.id} ({line.account_id.name}), Debit: {line.debit}, Credit: {line.credit}, Amount Currency: {line.amount_currency}, Currency: {line.currency_id.name if line.currency_id else 'N/A'}")

            # 初始化一个用于更新 move.line_ids 的命令列表
            move_line_commands = []
            bank_line_found = False

            for line in move.line_ids:
                # 找到凭证中的银行账户行 (借方行)
                if line.debit > 0 and not bank_line_found:  # 确保只处理第一条借方行作为银行行
                    # 对银行账户行进行更新操作：命令 (1, ID, {values})
                    move_line_commands.append((1, line.id, {
                        'debit': net_bank_amount_company_currency,
                        'amount_currency': net_bank_amount,
                    }))
                    _logger.info(f"Preparing update command for Bank Line (ID: {line.id}). New Debit: {net_bank_amount_company_currency}, New Amount Currency: {net_bank_amount}")
                    bank_line_found = True
                else:
                    # 对于其他现有行（如客户应收账款贷方行），保留原样：命令 (1, ID, {})
                    move_line_commands.append((1, line.id, {}))

            if not bank_line_found:
                # 再次添加详细日志，如果仍未找到行，则提供更多上下文
                _logger.error(f"Failed to find the debit line in the payment journal entry for payment ID: {payment.id}. "
                              f"Please check the actual lines created by the payment.")
                raise UserError(_("Could not find the bank account line in the payment journal entry. "
                                  "Expected a debit line for inbound payment."))

            # 添加新的手续费借方行：命令 (0, 0, {values})
            move_line_commands.append((0, 0, {
                'account_id': self.fee_account_id.id,  # 手续费账户
                'name': _('Bank Fee'),  # 分录名称
                'debit': fee_amount_company_currency,  # 手续费金额（借方）
                'credit': 0.0,
                'currency_id': currency.id if currency != company_currency else False,
                'amount_currency': self.fee_amount,  # 交易货币金额
            }))
            _logger.info(
                f"Preparing create command for Bank Fee Line. Account: {self.fee_account_id.name}, Debit: {fee_amount_company_currency}, Amount Currency: {self.fee_amount}")

            # 将所有命令一次性写入 move.line_ids
            move.write({'line_ids': move_line_commands})
            _logger.info(f"Move lines updated using commands for Move ID: {move.id}.")

            # 此时，凭证行将变为：
            # 1. 借方：银行账户 (净金额) -> debit = net_bank_amount_company_currency
            # 2. 贷方：客户应收账款 (总金额) -> credit = self.amount_company_currency
            # 3. 借方：银行手续费账户 (手续费金额) -> debit = fee_amount_company_currency
            #
            # 借方总额 = net_bank_amount_company_currency + fee_amount_company_currency
            #          = (self.amount_company_currency - fee_amount_company_currency) + fee_amount_company_currency
            #          = self.amount_company_currency
            # 贷方总额 = self.amount_company_currency
            # 借贷总额现在是平衡的。

        # 最后，过账付款。Odoo 会在过账时自动验证会计凭证的平衡性。
        payment.action_post()
        _logger.info(f"Payment {payment.id} has been posted successfully.")

        return {'type': 'ir.actions.act_window_close'}
